#include "diskTest.h"

option opt = {
        .color= true,
        .help = false,
        .random = false,
        .force = false,
        .test = false,
        .logLevel = 1,
        .fp = NULL,
        .started = false,
        .start = 0,
        .sized = false,
        .size = 0,
        .seeded = false,
        .seed = -1,
        .creat = false,

        // IT IS NOT USE
        .end = 0
};
#ifndef _GUI
static void opt_file(char *path) {
        if (opt.fp != NULL)
                error_se(_("File give duper"));
        if (access(path, F_OK)) {
                opt.creat = true;
                if ((opt.fp = fopen64(path, "ab+")) == NULL)
                        perr_e(_("Fopen Err"));
        } else {
                if (access(path, R_OK | W_OK))
                        perr_e(_("File access Err"));
                if ((opt.fp = fopen64(path, "rb+")) == NULL)
                        perr_e("Fopen Err");
        }
}
// *read will not '\0'
static void opt_getnum(bool *turn, uint64_t *where, char *read) {
        if (*turn)
                error_se(_("CMD Line give duper."));
        *turn = true;
        char *end;
        *where = strtoll(read, &end, 10);
        if (end == read || *end != '\0')
                opt_err();
}
#define set_val(turn, where)                                    \
        j++;                                                    \
        if (arg[j] == '\0') {                                   \
                if (!(++i<ac) || av[i][0] == '\0')              \
                        opt_err();                              \
                opt_getnum(&(turn), &(where), av[i]);           \
        } else {                                                \
                opt_getnum(&(turn), &(where), &av[i][j]);       \
        }                                                       \
        goto next_cmd;
void get_opt(int ac, char **av) {
        if (ac == 1)
                get_help();
        for (int i = 1 ; i < ac ; i++) {
                char *arg = av[i];
                if (arg[0] != '-' || strcmp("-", arg) == 0)
                        opt_err();
                if (strcmp("--", arg) == 0) {
                        if (!(++i < ac))
                                opt_err();
                        opt_file(av[i]);
                        continue;
                }
                for (int j = 1 ; arg[j] != '\0' ; j++) {
                        switch (arg[j]) {
                                default: opt_err(); break;
                                case 'h': opt.help = true; break;
                                case 'q': opt.logLevel = 0; break;
                                case 'v': opt.logLevel = 2; break;
                                case 'F': opt.force = true; break;
                                case 't': opt.test = true; break;
                                case 'r': opt.random = true; break;
                                case 'C': opt.color = false; break;
                                case 'c': opt.color = true; break;

                                case 's': set_val(opt.started, opt.start);
                                case 'n': set_val(opt.sized, opt.size);
                                case 'S': set_val(opt.seeded, opt.seed);
                        }
                }
                next_cmd: (void)0;
        }
        if (opt.help)
                get_help();
        if (opt.fp == NULL)
                error_se(_("Not Open File"));
        if (opt.creat) {
                if (!opt.seeded && (opt.started && opt.start == 0) && !opt.sized)
                        error_se(_("File not exist"));
                opt.end = opt.size - 1;
                return;
        }
        fseeko64(opt.fp, 0, SEEK_END);
        size_t file_end = ftello64(opt.fp) - 1;
        if (file_end == (size_t)-1)
                fprintf(stderr, _("Size read fail\n"));
        if (opt.started && file_end < opt.start)
                error_se(_("Start at the file's end"));
        if (opt.sized) {
                opt.end = opt.start + (opt.size - 1);
                if (file_end < opt.end) {
                        error_se(_("CMD-size is bigger then File-size"));
                }
        } else {
                opt.end = file_end;
        }
}
#undef set_val
#endif // !_GUI
